package de.home.filter;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import de.home.util.Utils;

/**
 * Servlet Filter implementation class IPFilter
 */
public class AuthentificationFilter implements Filter {

   private static final Logger LOG = LogManager.getLogger(AuthentificationFilter.class);

   public AuthentificationFilter() {
      // TODO Auto-generated constructor stub
   }

   /**
    * @see Filter#destroy()
    */
   public void destroy() {
      // TODO Auto-generated method stub
   }

   /**
    * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
    */
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
         throws IOException, ServletException {
      HttpServletRequest request = (HttpServletRequest) servletRequest;
      HttpServletResponse response = (HttpServletResponse) servletResponse;

      String ownIPAddress = InetAddress.getLocalHost().getHostAddress();
      String remoteIPAddr = request.getRemoteAddr();
      String subnetmask;
      try {
         subnetmask = Utils.getLocalSubnetMask();
      } catch (Exception e) {
         LOG.error(e.getMessage());
         return;
      }

      boolean isInLocalNetwork = sameNetwork(ownIPAddress, remoteIPAddr, subnetmask);

      if ( isInLocalNetwork ) {
         LOG.info("Request from IP '{}' is from LAN.", remoteIPAddr);
         chain.doFilter(request, response);
      } else {
         LOG.info("Request from IP '{}' is not from LAN.", remoteIPAddr);

         HttpSession session = request.getSession(true);

         LOG.info("fuck {}", session.getAttribute("login"));

         if ( session.getAttribute("login") != null ) {
            chain.doFilter(request, response);
            return;
         }

         String name = request.getParameter("j_username");
         String passwd = request.getParameter("j_password");

         LOG.info("name = {}", name);
         LOG.info("passwd = {}", passwd);

         session.setAttribute("login", true);

         request.setAttribute("dest", request.getRequestURL());

         request.getRequestDispatcher("/login.jsp").forward(request, response);
         return;
      }

   }

   /**
    * @see Filter#init(FilterConfig)
    */
   public void init(FilterConfig fConfig) throws ServletException {
      // TODO Auto-generated method stub
   }

   private boolean sameNetwork(String ip1, String ip2, String mask) throws UnknownHostException {

      byte[] a1 = InetAddress.getByName(ip1).getAddress();
      byte[] a2 = InetAddress.getByName(ip2).getAddress();
      byte[] m = InetAddress.getByName(mask).getAddress();

      for (int i = 0; i < a1.length; i++)
         if ( (a1[i] & m[i]) != (a2[i] & m[i]) )
            return false;

      return true;

   }

}
